import { useUserStore } from '@/store'
import { getEnvBaseUrl } from '@/utils'
import { platform } from '@/utils/platform'

export type CustomRequestOptions = UniApp.RequestOptions & {
  query?: Record<string, any>
  /** 出错时是否隐藏错误提示 */
  hideErrorToast?: boolean
} & IUniUploadFileOptions // 添加uni.uploadFile参数类型

// 简单的 query 字符串序列化函数
function stringify(obj: Record<string, any>): string {
  return Object.keys(obj)
    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`)
    .join('&')
}

// 请求基准地址
const baseUrl = getEnvBaseUrl()

// 拦截器配置
const httpInterceptor = {
  // 拦截前触发
  invoke(options: CustomRequestOptions) {
    // 接口请求支持通过 query 参数配置 queryString
    if (options.query) {
      const queryStr = stringify(options.query)
      if (options.url.includes('?')) {
        options.url += `&${queryStr}`
      }
      else {
        options.url += `?${queryStr}`
      }
    }
    // 非 http 开头需拼接地址
    if (!options.url.startsWith('http')) {
      // #ifdef H5
      if (import.meta.env.VITE_APP_PROXY === 'true') {
        // 自动拼接代理前缀
        options.url = import.meta.env.VITE_APP_PROXY_PREFIX + options.url
      }
      else {
        options.url = baseUrl + options.url
      }
      // #endif
      // 非H5正常拼接
      // #ifndef H5
      options.url = baseUrl + options.url
      // #endif
      // TIPS: 如果需要对接多个后端服务，也可以在这里处理，拼接成所需要的地址
    }
    // 1. 请求超时
    options.timeout = 10000 // 10s
    // 2. （可选）添加小程序端请求头标识
    options.header = {
      platform, // 可选，与 uniapp 定义的平台一致，告诉后台来源
      ...options.header,
    }
    // 无需认证的接口列表
    const noAuthUrls = [
      '/tenant/enable/status',
      '/auth/login',
      '/client/sys-user/auth/register',
      '/captcha/status',
      '/captcha/get',
      '/captcha/check',
    ]

    // 判断是否需要添加认证头
    const needAuth = !noAuthUrls.some(url => options.url.includes(url))

    // 3. 添加 token 请求头标识
    if (needAuth) {
      const userStore = useUserStore()
      const { token } = userStore.userInfo as unknown as IUserInfo
      if (token) {
        options.header.Authorization = `Bearer ${token}`
      }
    }

    // 4. 添加菜单类型请求头
    const menuType = uni.getStorageSync('menuType') || 'Client'
    options.header.MenuType = menuType

    // 5. 添加租户ID请求头
    const tenantId = uni.getStorageSync('tenantId')
    if (tenantId) {
      options.header['Tenant-Id'] = tenantId
    }
    else {
      options.header['Tenant-Id'] = 'GLOWXQ'
    }
  },
}

export const requestInterceptor = {
  install() {
    // 拦截 request 请求
    uni.addInterceptor('request', httpInterceptor)
    // 拦截 uploadFile 文件上传
    uni.addInterceptor('uploadFile', httpInterceptor)
  },
}
